use anyhow::{Context, Result};
use std::collections::HashMap;
use std::net::{IpAddr, Ipv4Addr};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
use tracing::{debug, error, info};
use md5;
use rand::Rng;
use if_addrs;

#[derive(Debug, Clone)]
pub struct AuthInfo {
    pub realm: String,
    pub nonce: String,
    pub algorithm: String,
    pub qop: Option<String>,
}

#[derive(Debug, Clone)]
pub struct SipRequest {
    pub method: String,
    pub uri: String,
    pub version: String,
    pub headers: HashMap<String, String>,
    pub body: Option<Vec<u8>>,
}

#[derive(Debug, Clone)]
pub struct SipResponse {
    pub version: String,
    pub status_code: u16,
    pub reason_phrase: String,
    pub headers: HashMap<String, String>,
    pub body: Option<Vec<u8>>,
}

#[derive(Debug, Clone)]
pub struct SdpInfo {
    pub remote_ip: String,
    pub remote_port: u16,
    pub payload_types: Vec<u8>,
}

pub struct SipMessageHandler {
    buffer: Vec<u8>,
    server_ip: String,
}

impl SipMessageHandler {
    pub fn new(server_ip: String) -> Self {
        Self {
            buffer: Vec::new(),
            server_ip,
        }
    }

    pub fn get_local_ip(&self) -> String {
        // 动态获取本机IP地址，优先选择与目标服务器在同一网段的IP
        match get_local_ip_address_for_target(&self.server_ip) {
            Ok(ip) => {
                debug!("选择本机IP地址: {} (目标服务器: {})", ip, self.server_ip);
                ip
            },
            Err(e) => {
                error!("无法获取本机IP地址: {}, 使用默认IP", e);
                "127.0.0.1".to_string()
            }
        }
    }

    fn get_local_port(&self) -> String {
        // 简单返回本地端口，实际应用中可能需要更复杂的逻辑
        "53751".to_string()
    }

    pub fn get_server_ip(&self) -> &str {
        &self.server_ip
    }

    pub async fn read_sip_message(&mut self, stream: &mut TcpStream) -> Result<Option<String>> {
        let mut buffer = [0; 1024];
        
        // 增加超时时间，NOTIFY消息可能需要更长时间
        let timeout = tokio::time::Duration::from_secs(10);
        let read_result = tokio::time::timeout(timeout, stream.read(&mut buffer)).await;
        
        let n = match read_result {
            Ok(Ok(n)) => n,
            Ok(Err(e)) => {
                error!("读取TCP流时出错: {}", e);
                return Err(e.into());
            }
            Err(_) => {
                debug!("读取SIP消息超时，当前缓冲区大小: {} 字节", self.buffer.len());
                if !self.buffer.is_empty() {
                    debug!("缓冲区内容: {:?}", String::from_utf8_lossy(&self.buffer));
                }
                return Ok(None);
            }
        };
        
        if n == 0 {
            debug!("TCP连接关闭");
            return Ok(None); // 连接关闭
        }

        info!("读取到 {} 字节数据", n);
        self.buffer.extend_from_slice(&buffer[..n]);
        info!("缓冲区总大小: {} 字节", self.buffer.len());
        
        // 查找SIP消息的结束标记（双回车换行）
        if let Some(end_pos) = find_sip_message_end(&self.buffer) {
            let message = String::from_utf8_lossy(&self.buffer[..end_pos]).to_string();
            info!("找到完整SIP消息，长度: {} 字节", end_pos);
            info!("消息内容: {}", message.lines().next().unwrap_or(""));
            self.buffer.drain(..end_pos);
            return Ok(Some(message));
        }

        // 如果消息不完整，继续读取更多数据
        debug!("消息不完整，继续读取更多数据...");
        Ok(None) // 消息不完整，继续读取
    }

    pub async fn send_sip_message(&self, stream: &mut TcpStream, message: &str) -> Result<()> {
        stream.write_all(message.as_bytes()).await?;
        stream.flush().await?;
        debug!("发送SIP消息: {}", message);
        Ok(())
    }

    pub fn parse_sip_request(&self, message: &str) -> Result<SipRequest> {
        let lines: Vec<&str> = message.lines().collect();
        if lines.is_empty() {
            return Err(anyhow::anyhow!("空的SIP消息"));
        }

        let first_line = lines[0];
        let parts: Vec<&str> = first_line.split_whitespace().collect();
        if parts.len() != 3 {
            return Err(anyhow::anyhow!("无效的SIP请求行: {}", first_line));
        }

        let method = parts[0].to_string();
        let uri = parts[1].to_string();
        let version = parts[2].to_string();

        let mut headers = HashMap::new();
        let mut body_start = 0;

        // 解析头部
        for (i, line) in lines.iter().enumerate().skip(1) {
            if line.is_empty() {
                body_start = i + 1;
                break;
            }
            
            // 处理SIP头部，支持多种格式
            let line = line.trim();
            if line.is_empty() {
                continue;
            }
            
            // 查找第一个冒号的位置（SIP标准：第一个冒号分隔头部名称和值）
            if let Some(colon_pos) = line.find(':') {
                let key = line[..colon_pos].trim().to_string();
                let value = if colon_pos + 1 < line.len() {
                    line[colon_pos + 1..].trim().to_string()
                } else {
                    String::new()
                };
                
                if !key.is_empty() {
                    headers.insert(key, value);
                }
            }
        }

        // 解析消息体 - 改进消息体解析逻辑
        let body = if body_start < lines.len() {
            let body_lines = &lines[body_start..];
            let body_content = body_lines.join("\r\n");
            
            // 检查消息体是否为空或只包含空白字符
            if body_content.trim().is_empty() {
                None
            } else {
                Some(body_content.into_bytes())
            }
        } else {
            None
        };

        // 调试信息
        debug!("解析SIP请求: method={}, uri={}, headers_count={}, has_body={}", 
               method, uri, headers.len(), body.is_some());

        Ok(SipRequest {
            method,
            uri,
            version,
            headers,
            body,
        })
    }

    pub fn parse_sip_response(&self, message: &str) -> Result<SipResponse> {
        let lines: Vec<&str> = message.lines().collect();
        if lines.is_empty() {
            return Err(anyhow::anyhow!("空的SIP消息"));
        }

        let first_line = lines[0];
        let parts: Vec<&str> = first_line.split_whitespace().collect();
        if parts.len() < 3 {
            return Err(anyhow::anyhow!("无效的SIP响应行: {}", first_line));
        }

        let version = parts[0].to_string();
        let status_code = parts[1].parse::<u16>()?;
        let reason_phrase = parts[2..].join(" ");

        let mut headers = HashMap::new();
        let mut body_start = 0;

        // 解析头部
        for (i, line) in lines.iter().enumerate().skip(1) {
            if line.is_empty() {
                body_start = i + 1;
                break;
            }
            
            // 处理SIP头部，支持多种格式
            let line = line.trim();
            if line.is_empty() {
                continue;
            }
            
            // 查找第一个冒号的位置（SIP标准：第一个冒号分隔头部名称和值）
            if let Some(colon_pos) = line.find(':') {
                let key = line[..colon_pos].trim().to_string();
                let value = if colon_pos + 1 < line.len() {
                    line[colon_pos + 1..].trim().to_string()
                } else {
                    String::new()
                };
                
                if !key.is_empty() {
                    headers.insert(key, value);
                }
            }
        }

        // 解析消息体
        let body = if body_start < lines.len() {
            let body_lines = &lines[body_start..];
            Some(body_lines.join("\r\n").into_bytes())
        } else {
            None
        };

        Ok(SipResponse {
            version,
            status_code,
            reason_phrase,
            headers,
            body,
        })
    }

    pub fn create_invite_request(&self, target_uri: &str, from_uri: &str, call_id: &str, contact: &str) -> String {
        let sdp = self.create_sdp();
        let branch = format!("z9hG4bK-524287-1---{}", uuid::Uuid::new_v4().to_string().replace("-", ""));
        let tag = uuid::Uuid::new_v4().to_string().replace("-", "");
        
        format!(
            "INVITE {} SIP/2.0\r\n\
             Via: SIP/2.0/TCP {}:{};branch={};rport\r\n\
             Max-Forwards: 70\r\n\
             Contact: <{}>\r\n\
             To: <{}>\r\n\
             From: <{}>;tag={}\r\n\
             Call-ID: {}\r\n\
             CSeq: 1 INVITE\r\n\
             Allow: INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE\r\n\
             Content-Type: application/sdp\r\n\
             Supported: replaces, norefersub, extended-refer, timer, sec-agree, outbound, path, X-cisco-serviceuri\r\n\
             User-Agent: FreeSWITCH-SIP-CLI/1.0\r\n\
             Allow-Events: presence, kpml, talk, as-feature-event\r\n\
             Content-Length: {}\r\n\
             \r\n\
             {}",
            target_uri,
            self.get_local_ip(),
            self.get_local_port(),
            branch,
            contact,
            target_uri,
            from_uri,
            tag,
            call_id,
            sdp.len(),
            sdp
        )
    }

    pub fn create_ok_response(&self, request: &SipRequest, sdp: &str) -> String {
        format!(
            "SIP/2.0 200 OK\r\n\
             From: {}\r\n\
             To: {}\r\n\
             Call-ID: {}\r\n\
             CSeq: {}\r\n\
             Contact: <sip:client@127.0.0.1:5060>\r\n\
             Content-Type: application/sdp\r\n\
             Content-Length: {}\r\n\
             \r\n\
             {}",
            request.headers.get("From").unwrap_or(&"".to_string()),
            request.headers.get("To").unwrap_or(&"".to_string()),
            request.headers.get("Call-ID").unwrap_or(&"".to_string()),
            request.headers.get("CSeq").unwrap_or(&"".to_string()),
            sdp.len(),
            sdp
        )
    }

    pub fn create_bye_request(&self, target_uri: &str, call_id: &str, cseq: &str) -> String {
        format!(
            "BYE {} SIP/2.0\r\n\
             From: <sip:client@127.0.0.1:5060>\r\n\
             To: <{}>\r\n\
             Call-ID: {}\r\n\
             CSeq: {} BYE\r\n\
             \r\n",
            target_uri,
            target_uri,
            call_id,
            cseq
        )
    }

    pub fn create_ack_request(&self, call_id: &str) -> String {
        let local_ip = self.get_local_ip();
        let server_ip = self.get_server_ip();
        let branch = format!("z9hG4bK{}", uuid::Uuid::new_v4().to_string().replace("-", ""));
        let tag = uuid::Uuid::new_v4().to_string().replace("-", "");
        
        format!(
            "ACK sip:{} SIP/2.0\r\n\
             Via: SIP/2.0/TCP {}:{};branch={}\r\n\
             From: <sip:1000@{}>;tag={}\r\n\
             To: <sip:1001@{}>\r\n\
             Call-ID: {}\r\n\
             CSeq: 1 ACK\r\n\
             Contact: <sip:1000@{}:5061>\r\n\
             User-Agent: FreeSWITCH-SIP-CLI/1.0\r\n\
             Max-Forwards: 70\r\n\
             \r\n",
            call_id.split('@').next().unwrap_or("1001"),
            local_ip, self.get_local_port(),
            branch,
            server_ip, tag,
            server_ip,
            call_id,
            server_ip
        )
    }

    pub fn create_options_request(&self, target_uri: &str) -> String {
        let local_ip = self.get_local_ip();
        let server_ip = self.get_server_ip();
        let call_id = format!("{}@{}", uuid::Uuid::new_v4(), &local_ip);
        let branch = format!("z9hG4bK{}", uuid::Uuid::new_v4().to_string().replace("-", ""));
        let tag = uuid::Uuid::new_v4().to_string().replace("-", "");
        
        format!(
            "OPTIONS {} SIP/2.0\r\n\
             Via: SIP/2.0/TCP {}:{};branch={}\r\n\
             From: <sip:1000@{}>;tag={}\r\n\
             To: <{}>\r\n\
             Call-ID: {}\r\n\
             CSeq: 1 OPTIONS\r\n\
             Contact: <sip:1000@{}:5061>\r\n\
             User-Agent: FreeSWITCH-SIP-CLI/1.0\r\n\
             Max-Forwards: 70\r\n\
             \r\n",
            target_uri,
            local_ip, self.get_local_port(),
            branch,
            server_ip, tag,
            target_uri,
            call_id,
            server_ip
        )
    }

    pub fn create_simple_options_request(&self, target_uri: &str) -> String {
        let local_ip = self.get_local_ip();
        let server_ip = self.get_server_ip();
        let call_id = format!("{}@{}", uuid::Uuid::new_v4(), &local_ip);
        
        format!(
            "OPTIONS {} SIP/2.0\r\n\
             Call-ID: {}\r\n\
             CSeq: 1 OPTIONS\r\n\
             From: <sip:1000@{}>\r\n\
             To: <{}>\r\n\
             Via: SIP/2.0/TCP {}:{}\r\n\
             \r\n",
            target_uri,
            call_id,
            server_ip,
            target_uri,
            local_ip, self.get_local_port()
        )
    }

    pub fn create_register_request(&self, username: &str, password: &str, contact: &str) -> String {
        let local_ip = self.get_local_ip();
        let server_ip = self.get_server_ip();
        let call_id = format!("{}@{}", uuid::Uuid::new_v4(), &local_ip);
        let branch = format!("z9hG4bK-524287-1---{}", uuid::Uuid::new_v4().to_string().replace("-", ""));
        let tag = uuid::Uuid::new_v4().to_string().replace("-", "");
        let local_port = contact.split(':').last().unwrap_or("5060");
        
        format!(
            "REGISTER sip:{};transport=TCP SIP/2.0\r\n\
             Via: SIP/2.0/TCP {}:{};branch={};rport\r\n\
             Max-Forwards: 70\r\n\
             Contact: <sip:{}@{}:{};rinstance={};transport=TCP>\r\n\
             To: <sip:{}@{};transport=TCP>\r\n\
             From: <sip:{}@{};transport=TCP>;tag={}\r\n\
             Call-ID: {}\r\n\
             CSeq: 1 REGISTER\r\n\
             Expires: 600\r\n\
             Allow: INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE\r\n\
             Supported: replaces, norefersub, extended-refer, timer, sec-agree, outbound, path, X-cisco-serviceuri\r\n\
             User-Agent: Z 5.6.10 v2.10.20.10\r\n\
             Allow-Events: presence, kpml, talk, as-feature-event\r\n\
             Content-Length: 0\r\n\
             \r\n",
            username,
            local_ip, local_port,
            branch,
            username, local_ip, local_port, uuid::Uuid::new_v4().to_string().replace("-", ""),
            username, server_ip,
            username, server_ip, tag,
            call_id
        )
    }

    pub fn create_sdp(&self) -> String {
        format!(
            "v=0\r\n\
             o=Z 0 {} IN IP4 {}\r\n\
             s=Z\r\n\
             c=IN IP4 {}\r\n\
             t=0 0\r\n\
             m=audio {} RTP/AVP 0 8 101\r\n\
             a=rtpmap:0 PCMU/8000\r\n\
             a=rtpmap:8 PCMA/8000\r\n\
             a=rtpmap:101 telephone-event/8000\r\n\
             a=fmtp:101 0-16\r\n\
             a=sendrecv\r\n\
             a=rtcp-mux\r\n",
            chrono::Utc::now().timestamp(),
            self.get_local_ip(),
            self.get_local_ip(),
            rand::thread_rng().gen_range(49152..65535)
        )
    }

    pub fn parse_auth_header(&self, auth_header: &str) -> Result<AuthInfo> {
        let mut realm = String::new();
        let mut nonce = String::new();
        let mut algorithm = String::new();
        let mut qop = None;

        // 解析类似 "Digest realm="192.168.43.252", nonce="b7d47bfb-c2e2-4625-91f9-12372b017aee", algorithm=MD5, qop="auth"" 的字符串
        let parts: Vec<&str> = auth_header.split(',').collect();
        
        for part in parts {
            let part = part.trim();
            if part.starts_with("realm=") {
                realm = part[7..].trim_matches('"').to_string();
            } else if part.starts_with("nonce=") {
                nonce = part[7..].trim_matches('"').to_string();
            } else if part.starts_with("algorithm=") {
                algorithm = part[11..].to_string();
            } else if part.starts_with("qop=") {
                qop = Some(part[5..].trim_matches('"').to_string());
            }
        }

        Ok(AuthInfo {
            realm,
            nonce,
            algorithm,
            qop,
        })
    }

    pub fn create_auth_response(&self, auth_info: &AuthInfo, username: &str, password: &str, method: &str, uri: &str) -> String {
        let nc = "00000001";
        let cnonce = format!("{:x}", rand::random::<u32>());
        let qop = auth_info.qop.as_deref().unwrap_or("auth");

        // 计算HA1 = MD5(username:realm:password)
        let ha1_input = format!("{}:{}:{}", username, auth_info.realm, password);
        let ha1 = format!("{:x}", md5::compute(ha1_input.as_bytes()));

        // 计算HA2 = MD5(method:uri)
        let ha2_input = format!("{}:{}", method, uri);
        let ha2 = format!("{:x}", md5::compute(ha2_input.as_bytes()));

        // 计算response
        let response_input = if auth_info.qop.is_some() {
            format!("{}:{}:{}:{}:{}:{}", ha1, auth_info.nonce, nc, cnonce, qop, ha2)
        } else {
            format!("{}:{}:{}", ha1, auth_info.nonce, ha2)
        };
        let response = format!("{:x}", md5::compute(response_input.as_bytes()));

        format!(
            "Digest username=\"{}\",realm=\"{}\",nonce=\"{}\",uri=\"{}\",response=\"{}\",cnonce=\"{}\",nc={},qop={},algorithm={}",
            username, auth_info.realm, auth_info.nonce, uri, response, cnonce, nc, qop, auth_info.algorithm
        )
    }

    pub fn add_auth_header(&self, invite_message: &str, auth_response: &str) -> String {
        // 在Content-Length之前插入Proxy-Authorization头部
        let lines: Vec<&str> = invite_message.lines().collect();
        let mut new_lines = Vec::new();
        
        for line in lines {
            if line.starts_with("Content-Length:") {
                new_lines.push(format!("Proxy-Authorization: {}", auth_response));
            }
            new_lines.push(line.to_string());
        }
        
        new_lines.join("\r\n") + "\r\n"
    }

    pub fn create_authenticated_register_request(&self, username: &str, password: &str, contact: &str, auth_response: &str) -> String {
        let local_ip = self.get_local_ip();
        let server_ip = self.get_server_ip();
        let call_id = format!("{}@{}", uuid::Uuid::new_v4(), &local_ip);
        let branch = format!("z9hG4bK-524287-1---{}", uuid::Uuid::new_v4().to_string().replace("-", ""));
        let tag = uuid::Uuid::new_v4().to_string().replace("-", "");
        let local_port = contact.split(':').last().unwrap_or("5060");
        
        format!(
            "REGISTER sip:{};transport=TCP SIP/2.0\r\n\
             Via: SIP/2.0/TCP {}:{};branch={};rport\r\n\
             Max-Forwards: 70\r\n\
             Contact: <sip:{}@{}:{};rinstance={};transport=TCP>\r\n\
             To: <sip:{}@{};transport=TCP>\r\n\
             From: <sip:{}@{};transport=TCP>;tag={}\r\n\
             Call-ID: {}\r\n\
             CSeq: 2 REGISTER\r\n\
             Expires: 600\r\n\
             Allow: INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE\r\n\
             Supported: replaces, norefersub, extended-refer, timer, sec-agree, outbound, path, X-cisco-serviceuri\r\n\
             User-Agent: Z 5.6.10 v2.10.20.10\r\n\
             Authorization: {}\r\n\
             Allow-Events: presence, kpml, talk, as-feature-event\r\n\
             Content-Length: 0\r\n\
             \r\n",
            username,
            local_ip, local_port,
            branch,
            username, local_ip, local_port, uuid::Uuid::new_v4().to_string().replace("-", ""),
            username, server_ip,
            username, server_ip, tag,
            call_id,
            auth_response
        )
    }

    pub fn create_cancel_request(&self, target_uri: &str, call_id: &str, cseq: &str) -> String {
        let branch = format!("z9hG4bK-524287-1---{}", uuid::Uuid::new_v4().to_string().replace("-", ""));
        
        format!(
            "CANCEL {} SIP/2.0\r\n\
             Via: SIP/2.0/TCP {}:{};branch={};rport\r\n\
             Max-Forwards: 70\r\n\
             To: <{}>\r\n\
             From: <{}>;tag={}\r\n\
             Call-ID: {}\r\n\
             CSeq: {} CANCEL\r\n\
             User-Agent: FreeSWITCH-SIP-CLI/1.0\r\n\
             Content-Length: 0\r\n\
             \r\n",
            target_uri,
            self.get_local_ip(),
            self.get_local_port(),
            branch,
            target_uri,
            target_uri.replace("sip:", "sip:1000@").replace(";transport=TCP", ";transport=TCP"),
            uuid::Uuid::new_v4().to_string().replace("-", ""),
            call_id,
            cseq
        )
    }

    pub fn parse_sdp(&self, sdp_body: &str) -> Result<SdpInfo> {
        let mut remote_ip = String::new();
        let mut remote_port = 0;
        let mut payload_types = Vec::new();
        
        for line in sdp_body.lines() {
            let line = line.trim();
            
            if line.starts_with("c=IN IP4 ") {
                // 解析连接信息行
                let parts: Vec<&str> = line.split_whitespace().collect();
                if parts.len() >= 3 {
                    remote_ip = parts[2].to_string();
                }
            } else if line.starts_with("m=audio ") {
                // 解析媒体信息行
                let parts: Vec<&str> = line.split_whitespace().collect();
                if parts.len() >= 2 {
                    if let Ok(port) = parts[1].parse::<u16>() {
                        remote_port = port;
                    }
                }
                
                // 解析负载类型
                if parts.len() >= 4 {
                    for i in 3..parts.len() {
                        if let Ok(pt) = parts[i].parse::<u8>() {
                            payload_types.push(pt);
                        }
                    }
                }
            }
        }
        
        if remote_ip.is_empty() || remote_port == 0 {
            return Err(anyhow::anyhow!("无法从SDP中解析RTP地址和端口"));
        }
        
        Ok(SdpInfo {
            remote_ip,
            remote_port,
            payload_types,
        })
    }

}

fn find_sip_message_end(buffer: &[u8]) -> Option<usize> {
    debug!("查找SIP消息结束标记，缓冲区大小: {} 字节", buffer.len());
    
    // 查找双回车换行 (\r\n\r\n)
    for i in 0..buffer.len().saturating_sub(3) {
        if buffer[i] == b'\r' && buffer[i + 1] == b'\n' && 
           buffer[i + 2] == b'\r' && buffer[i + 3] == b'\n' {
            
            debug!("找到双回车换行标记，位置: {}", i);
            
            // 检查是否有Content-Length头部
            let message_str = String::from_utf8_lossy(&buffer[..i + 4]);
            debug!("消息头部: {}", message_str.lines().next().unwrap_or(""));
            
            if let Some(content_length) = extract_content_length(&message_str) {
                debug!("找到Content-Length: {}", content_length);
                // 如果有Content-Length，需要读取完整的消息体
                let total_length = i + 4 + content_length;
                debug!("计算的总长度: {} 字节", total_length);
                
                if buffer.len() >= total_length {
                    debug!("缓冲区足够大，返回完整消息长度: {}", total_length);
                    return Some(total_length);
                } else {
                    debug!("缓冲区不够大，需要更多数据，当前: {}，需要: {}", buffer.len(), total_length);
                    return None; // 消息体不完整，继续等待
                }
            } else {
                debug!("没有Content-Length，消息在双回车换行处结束: {}", i + 4);
                // 没有Content-Length，消息在双回车换行处结束
                return Some(i + 4);
            }
        }
    }
    
    debug!("没有找到双回车换行标记");
    debug!("缓冲区前100字节: {:?}", String::from_utf8_lossy(&buffer[..buffer.len().min(100)]));
    None
}

fn extract_content_length(message: &str) -> Option<usize> {
    for line in message.lines() {
        if line.to_lowercase().starts_with("content-length:") {
            if let Some(value) = line.split(':').nth(1) {
                return value.trim().parse::<usize>().ok();
            }
        }
    }
    None
}

pub struct SipTransaction {
    pub call_id: String,
    pub state: SipTransactionState,
    pub request: Option<SipRequest>,
    pub response: Option<SipResponse>,
}

#[derive(Debug, Clone)]
pub enum SipTransactionState {
    Trying,
    Proceeding,
    Completed,
    Terminated,
}

impl SipTransaction {
    pub fn new(call_id: String) -> Self {
        Self {
            call_id,
            state: SipTransactionState::Trying,
            request: None,
            response: None,
        }
    }
}

/// 获取本机IP地址
fn get_local_ip_address() -> Result<String> {
    // 尝试连接到外部地址来获取本机IP
    if let Ok(stream) = std::net::TcpStream::connect("8.8.8.8:80") {
        if let Ok(local_addr) = stream.local_addr() {
            return Ok(local_addr.ip().to_string());
        }
    }
    
    // 如果上面的方法失败，尝试获取所有网络接口
    for interface in if_addrs::get_if_addrs()? {
        // 跳过回环接口和IPv6地址
        if !interface.is_loopback() && interface.addr.ip().is_ipv4() {
            return Ok(interface.addr.ip().to_string());
        }
    }
    
    Err(anyhow::anyhow!("无法获取本机IP地址"))
}

/// 获取本机IP地址，优先选择与目标服务器在同一网段的IP
fn get_local_ip_address_for_target(target_ip: &str) -> Result<String> {
    // 解析目标IP地址
    let target_ip_addr = target_ip.parse::<std::net::Ipv4Addr>()
        .map_err(|_| anyhow::anyhow!("无效的目标IP地址: {}", target_ip))?;
    
    // 获取所有网络接口
    let interfaces = if_addrs::get_if_addrs()?;
    let mut same_subnet_ips = Vec::new();
    let mut other_ips = Vec::new();
    
    for interface in interfaces {
        // 跳过回环接口和IPv6地址
        if interface.is_loopback() || !interface.addr.ip().is_ipv4() {
            continue;
        }
        
        if let if_addrs::IfAddr::V4(addr) = &interface.addr {
            let ip = addr.ip;
            let netmask = addr.netmask;
            
            // 计算前缀长度
            let mask_u32 = u32::from(netmask);
            let prefix_len = if mask_u32 == 0 {
                0
            } else {
                (32 - mask_u32.trailing_zeros()) as u8
            };
            
            debug!("接口 {}: IP={}, 子网掩码={}, 前缀长度={}", interface.name, ip, netmask, prefix_len);
            
            // 使用实际的子网掩码检查是否在同一网段
            if is_same_subnet(ip, target_ip_addr, prefix_len) {
                debug!("IP {} 与目标 {} 在同一网段 (前缀长度: {})", ip, target_ip_addr, prefix_len);
                same_subnet_ips.push(ip.to_string());
            } else {
                debug!("IP {} 与目标 {} 不在同一网段 (前缀长度: {})", ip, target_ip_addr, prefix_len);
                other_ips.push(ip.to_string());
            }
        }
    }
    
    // 优先返回同一网段的IP
    if !same_subnet_ips.is_empty() {
        debug!("找到与目标服务器在同一网段的IP: {:?}", same_subnet_ips);
        return Ok(same_subnet_ips[0].clone());
    }
    
    // 如果没有同一网段的IP，返回其他IP
    if !other_ips.is_empty() {
        debug!("未找到同一网段IP，使用其他IP: {:?}", other_ips);
        return Ok(other_ips[0].clone());
    }
    
    // 如果都没有，尝试连接到外部地址来获取本机IP
    if let Ok(stream) = std::net::TcpStream::connect("8.8.8.8:80") {
        if let Ok(local_addr) = stream.local_addr() {
            return Ok(local_addr.ip().to_string());
        }
    }
    
    Err(anyhow::anyhow!("无法获取本机IP地址"))
}

/// 检查两个IP地址是否在同一子网
fn is_same_subnet(ip1: std::net::Ipv4Addr, ip2: std::net::Ipv4Addr, prefix_len: u8) -> bool {
    let mask = if prefix_len == 0 {
        0
    } else {
        u32::MAX << (32 - prefix_len)
    };
    
    let network1 = u32::from(ip1) & mask;
    let network2 = u32::from(ip2) & mask;
    
    network1 == network2
} 